<?php

class User_Model_GroupRow extends Pldkp_Db_Table_Row_Abstract
{
    public function removeUser(User_Model_UserRow $user)
    {
        if ($this->is_default) {
            return false;
        }
        
        $usersGroupsTable = new User_Model_UsersGroups();
        $select = $usersGroupsTable->select();
        $select->where('user_id = ?', $user->id);
        $select->where('group_id = ?', $this->id);
        
        $row = $usersGroupsTable->fetchRow($select);
        
        if ($row) {
            return $row->delete() > 0;
        }
        
        return false;
    }
    
    public function addUser(User_Model_UserRow $user)
    {
        if ($this->is_default) {
            return false;
        }
        
        $usersGroupsTable = new User_Model_UsersGroups();
        $select = $usersGroupsTable->select();
        $select->where('user_id = ?', $user->id);
        $select->where('group_id = ?', $this->id);
        
        if (count($usersGroupsTable->fetchRow($select)) > 0) {
            return false;
        }
        
        $userGroup = $usersGroupsTable->fetchNew();
        $userGroup->user_id = $user->id;
        $userGroup->group_id = $this->id;
        return $userGroup->save();
    }
    
    public function addRight($right)
    {
        $groupsRightsTable = new User_Model_GroupsRights();
        $select = $groupsRightsTable->select();
        $select->where('right_id = ?', $right->id);
        $select->where('group_id = ?', $this->id);
        
        if (count($groupsRightsTable->fetchRow($select)) > 0) {
            return false;
        }
        
        $groupRight = $groupsRightsTable->fetchNew();
        $groupRight->right_id = $right->id;
        $groupRight->group_id = $this->id;
        return $groupRight->save();
    }
    
    public function removeRight($right)
    {
        $groupsRightsTable = new User_Model_GroupsRights();
        $select = $groupsRightsTable->select();
        $select->where('right_id = ?', $right->id);
        $select->where('group_id = ?', $this->id);
        
        $row = $groupsRightsTable->fetchRow($select);
        
        if ($row) {
            return $row->delete() > 0;
        }
        
        return false;
    }
    
    public function getAllowedResources($includeParents = true)
    {
        $resources = array();
        
        if ($includeParents) {
            $parentGroup = $this->findParentRow('User_Model_Groups');
            if ($parentGroup) {
                $resources = $parentGroup->getAllowedResources(true);
            }
        }
        
        $rights = $this->findManyToManyRowset('User_Model_Rights', 'User_Model_GroupsRights');
        foreach ($rights as $right) {
            $rightReources = $right->findDependentRowset('User_Model_Resources');
            foreach ($rightReources as $resource) {
                $resources[] = $resource;
            }
        }
        
        return $resources;
    }
    
    /**
     * Make sure that any group having this group as parent is adjusted.
     * This can not be handled with a cascade.
     * 
     */
    public function delete()
    {
        // Not sure that the id is retrivable after delte
        $id = $this->id;
        
        if (!parent::delete()) {
            return false;
        }
        
        $childGroups = User_Model_Groups::getBy('parent_group_id', $id);
        foreach ($childGroups as $childGroup) {
            $childGroup->parent_group_id = null;
            $childGroup->save();
        }
        
        return true;
    }
    
    
    public function leadsToParentLoop($groupIdChain = array())
    {
        // If it does not yet exists it will not have any children
        if (!$this->exists()) {
            return false;
        }
        
        // If this group has already been visited we are in trouble
        if (in_array($this->id, $groupIdChain)) {
            return true;
        }
        
        $parentGroup = $this->findParentRow('User_Model_Groups');
        if (!$parentGroup) {
            return false;
        }
        
        $groupIdChain[] = $this->id;
        return $parentGroup->leadsToParentLoop($groupIdChain);
    }
    
    public function validate()
    {
        // Make sure that a group is not its own parent
        if ($this->exists() && $this->id == $this->parent_group_id) {
            return false;
        }
        
        if ($this->leadsToParentLoop()) {
            return false;
        }
        
        return true;
    }
}